package org.linlinjava.litemall.db.service;

import com.alibaba.fastjson.JSONObject;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import org.apache.commons.lang3.StringUtils;
import org.linlinjava.litemall.db.dao.LitemallDisputeGoodsMapper;
import org.linlinjava.litemall.db.dao.LitemallDisputeOrderMapper;
import org.linlinjava.litemall.db.dao.LitemallDisputeRecordMapper;
import org.linlinjava.litemall.db.domain.*;
import org.linlinjava.litemall.db.util.BadWordUtil;
import org.linlinjava.litemall.db.util.DisputeConstant;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.text.SimpleDateFormat;
import java.time.LocalDateTime;
import java.util.*;

@Service
public class LitemallDisputeService {
    @Resource
    LitemallDisputeGoodsMapper disputeGoodsMapper;
    @Resource
    LitemallDisputeOrderMapper disputeOrderMapper;
    @Resource
    LitemallDisputeRecordMapper disputeRecordMapper;
    @Autowired
    LitemallCustomerService customerService;
    @Autowired
    LitemallBrandService brandService;
    @Autowired
    LitemallOrderGoodsService orderGoodsService;

    /**
     * 新建争议
     * @param userId
     * @param brandId
     * @param orderId
     * @param goodsList
     * @param reason
     * @param picList
     * @param type
     */
    public void createDispute(Integer userId, Integer brandId, Integer orderId, List<JSONObject> goodsList, String reason, List<String> picList, Short type) {
        LitemallDisputeOrder disputeOrder = new LitemallDisputeOrder();
        disputeOrder.setCreateTime(LocalDateTime.now());
        disputeOrder.setUpdateTime(LocalDateTime.now());
        disputeOrder.setOrderId(orderId);
        disputeOrder.setUserId(userId);
        disputeOrder.setBrandId(brandId);
        disputeOrder.setType(type);
        disputeOrder.setState(DisputeConstant.SUBMITTED);
        disputeOrder.setDisputeSn("d" + new SimpleDateFormat("yyHHddmmMMSSS").format(new Date()) + (int)(Math.random()*(9999-1000+1)+1000));
        disputeOrderMapper.insertSelective(disputeOrder);

        reason = DisputeConstant.RECORD_CREATE  + reason;
        recording(disputeOrder.getId(), reason, picList, (short)0);

        List<LitemallDisputeGoods> disputeGoods = parserGoods(goodsList, disputeOrder.getId());
        for (LitemallDisputeGoods goods : disputeGoods) {
            goods.setCreateTime(LocalDateTime.now());
            goods.setUpdateTime(LocalDateTime.now());
            disputeGoodsMapper.insertSelective(goods);
        }
    }

    /**
     * 回复争议
     * @param disputeOrder
     * @param reason
     * @param picList
     * @param agree
     */
    public void replyDispute(LitemallDisputeOrder disputeOrder, String reason, List<String> picList, Boolean agree) {

        if (agree) {
            disputeOrder.setState(DisputeConstant.REFUNDING);
            reason = DisputeConstant.RECORD_REPLY_AGREE + reason;
        }
        else {
            disputeOrder.setState(DisputeConstant.REFUSED);
            reason = DisputeConstant.RECORD_REPLY_DISAGREE + reason;
        }
        updateWithOptimisticLocker(disputeOrder);
        recording(disputeOrder.getId(), reason, picList, (short) 1);
    }

    /**
     * 记录
     * @param disputeId
     * @param msg
     * @param picList
     * @param source
     */
    public void recording(Integer disputeId, String msg, List<String> picList, Short source) {
        LitemallDisputeRecord record = new LitemallDisputeRecord();
        record.setCreateTime(LocalDateTime.now());
        record.setSource(source);
        record.setDisputeId(disputeId);
        if (msg != null) {
            record.setMessage(BadWordUtil.replaceBadWord(msg, 2, "**"));
        }
        if (picList != null) {
            record.setPic(picList.toArray(new String[]{}));
        }
        disputeRecordMapper.insertSelective(record);
    }

    public void rule(LitemallDisputeOrder disputeOrder, Boolean support, String reason, List<String> picList) {
        disputeOrder.setState(support ? DisputeConstant.REFUNDING : DisputeConstant.COMPLETED);
        reason = support ? DisputeConstant.RECORD_RULE_PASS + reason : DisputeConstant.RECORD_RULE_FAIL + reason;
        updateWithOptimisticLocker(disputeOrder);
        recording(disputeOrder.getId(), reason, picList, (short) 2);
    }

    public void recheck(LitemallDisputeOrder disputeOrder, boolean insurance, String reason, List<String> picList) {
        if (insurance) {
            disputeOrder.setState(DisputeConstant.RECHECKING);
            reason = DisputeConstant.RECORD_RECHECK_WAIT + reason;
        }
        else {
            disputeOrder.setState(DisputeConstant.WAIT_PAYING);
            reason = DisputeConstant.RECORD_RECHECK_PAY + reason;
        }
        updateWithOptimisticLocker(disputeOrder);
        recording(disputeOrder.getId(), reason, picList, (short) 2);
    }

    private List<LitemallDisputeGoods> parserGoods(List<JSONObject> param, Integer disputeId) {
        List<LitemallDisputeGoods> disputeGoods = new LinkedList<>();

        for (JSONObject object : param) {
            LitemallDisputeGoods goods = new LitemallDisputeGoods();
            goods.setDisputeId(disputeId);
            goods.setNum(object.getInteger("num"));
            goods.setOrderGoodsId(object.getInteger("orderGoodsId"));
            goods.setState(DisputeConstant.SUBMITTED);
            disputeGoods.add(goods);
        }
        return disputeGoods;
    }

    public LitemallDisputeOrder findOrderDetailById(Integer id) {
        LitemallDisputeOrder disputeOrder = disputeOrderMapper.selectByPrimaryKey(id);
        return findOrderDetail(disputeOrder);
    }

    public LitemallDisputeOrder findOrderDetail(LitemallDisputeOrder disputeOrder) {
        Map<String, Object> map = new LinkedHashMap<>();
        map.put("disputeGoods", queryGoodsByOId(disputeOrder.getId()) );
        map.put("disputeRecord", queryRecordByOId(disputeOrder.getId()));
        disputeOrder.setDetailInfo(map);
        return disputeOrder;
    }

    public LitemallDisputeOrder findOrderById(Integer id) {
        return disputeOrderMapper.selectByPrimaryKey(id);
    }

    public List<LitemallDisputeGoods> queryGoodsByOId(Integer id) {
        LitemallDisputeGoodsExample  example = new LitemallDisputeGoodsExample();
        example.or().andDisputeIdEqualTo(id);
        List<LitemallDisputeGoods> list = disputeGoodsMapper.selectByExample(example);
        return detailGoodsInfo(list);
    }

    public List<LitemallDisputeRecord> queryRecordByOId(Integer id) {
        LitemallDisputeRecordExample example = new LitemallDisputeRecordExample();
        example.or().andDisputeIdEqualTo(id);
        return disputeRecordMapper.selectByExample(example);
    }

    public PageInfo<LitemallDisputeOrder> queryOrder(Integer userId, Integer brandId, Integer page, Integer pageSize) {
        LitemallDisputeOrderExample example = new LitemallDisputeOrderExample();
        LitemallDisputeOrderExample.Criteria criteria = example.createCriteria();
        if (userId != null && userId > 0) {
            criteria.andUserIdEqualTo(userId);
        }
        if (brandId != null && brandId > 0) {
            criteria.andBrandIdEqualTo(brandId);
        }
        example.setOrderByClause("id desc");
        PageHelper.startPage(page, pageSize);
        return appendDetail( new PageInfo<>(disputeOrderMapper.selectByExample(example)));
    }

    public PageInfo<LitemallDisputeOrder> queryOrder(String user, String brand, Integer page, Integer pageSize) {
        List<LitemallCustomer> customerList = customerService.query(user);
        List<LitemallBrand> brandList = brandService.queryByName(brand);
        List<Integer> customerId = new LinkedList<>();
        List<Integer> brandId = new LinkedList<>();
        getIdList(customerList, customerId, brandList, brandId);
        LitemallDisputeOrderExample example = new LitemallDisputeOrderExample();
        LitemallDisputeOrderExample.Criteria criteria = example.createCriteria();
        if (StringUtils.isNotEmpty(user)) {
            criteria.andUserIdIn(customerId);
        }
        if (StringUtils.isNotEmpty(brand)) {
            criteria.andBrandIdIn(brandId);
        }
        example.setOrderByClause("id desc");
        PageHelper.startPage(page, pageSize);
        return appendDetail( new PageInfo<>(disputeOrderMapper.selectByExample(example)));
    }

    public PageInfo<LitemallDisputeOrder> appendDetail(PageInfo<LitemallDisputeOrder> pageInfo) {
        List<LitemallDisputeOrder> list = pageInfo.getList();
        List<LitemallDisputeOrder> temp = new LinkedList<>();
        for (LitemallDisputeOrder order : list)  {
            temp.add(findOrderDetail(order));
        }
        pageInfo.setList(temp);
        return pageInfo;
    }

    private void getIdList(List<LitemallCustomer> customerList, List<Integer> customerId, List<LitemallBrand> brandList, List<Integer> brandId) {
        for (LitemallCustomer customer : customerList) {
            customerId.add(customer.getId().intValue());
    }
        for (LitemallBrand brand : brandList) {
            brandId.add(brand.getId());
        }
    }

    public int updateWithOptimisticLocker(LitemallDisputeOrder order) {
        LocalDateTime preUpdateTime = order.getUpdateTime();
        order.setUpdateTime(LocalDateTime.now());
        return disputeOrderMapper.updateWithOptimisticLocker(preUpdateTime, order);
    }

    public LitemallDisputeGoods detailGoodsInfo(LitemallDisputeGoods goods) {
        Map<String, Object> map = new LinkedHashMap<>();
        map.put("detail", orderGoodsService.findById(goods.getOrderGoodsId()));
        goods.setDetailInfo(map);
        return goods;
    }

    public List<LitemallDisputeGoods> detailGoodsInfo(List<LitemallDisputeGoods> goods) {
        for (LitemallDisputeGoods g : goods) {
            g = detailGoodsInfo(g);
        }
        return goods;
    }

    public List<LitemallDisputeOrder> findActiveOrderByOId(Integer orderId) {
        LitemallDisputeOrderExample example = new LitemallDisputeOrderExample();
        example.or().andOrderIdEqualTo(orderId).andStateNotEqualTo(DisputeConstant.CANCELED);
        return disputeOrderMapper.selectByExample(example);
    }
    public LitemallDisputeOrder findOrderBySn(String sn) {
        LitemallDisputeOrderExample example = new LitemallDisputeOrderExample();
        example.or().andDisputeSnEqualTo(sn);
        return disputeOrderMapper.selectOneByExample(example);
    }

    public LitemallDisputeOrder findByBankCertificate(String fileName) {
        LitemallDisputeOrderExample example = new LitemallDisputeOrderExample();
        example.or().andPayIdEqualTo(fileName);
        return disputeOrderMapper.selectOneByExample(example);
    }
    //争议单  已完成的数量
    public  List<LitemallDisputeOrder> byBrandId320(Integer brandId){
        LitemallDisputeOrderExample example = new LitemallDisputeOrderExample();
        if (null !=brandId ||"".equals(brandId)){
        example.or().andBrandIdEqualTo(brandId).andStateEqualTo((short)320);}
        return disputeOrderMapper.selectByExampleSelective(example);
    }
    //争议单  本公司的数量
    public  List<LitemallDisputeOrder> byBrandId(Integer brandId){
        LitemallDisputeOrderExample example = new LitemallDisputeOrderExample();
        example.or().andBrandIdEqualTo(brandId);
        return disputeOrderMapper.selectByExampleSelective(example);
    }

}
